package com.ncmmall.mall.controller.business.live;

import com.ncmmall.application.business.live.LiveGoodsApplication;
import com.feijin.commons.exceptions.IllegalRequestException;
import com.feijin.commons.lang.Requires;
import com.feijin.commons.webs.Webs;
import com.ncmmall.domain.business.goods.Goods;
import com.ncmmall.domain.business.goods.channel.GoodsChannel;
import com.ncmmall.domain.business.goods.channel.QGoodsChannel;
import com.ncmmall.domain.business.live.LiveGoods;
import com.ncmmall.domain.business.live.QLiveGoods;
import com.ncmmall.domain.security.user.WebUser;
import com.ncmmall.mall.params.PageParams;
import com.ncmmall.querychannel.QueryPage;
import com.ncmmall.querychannel.QueryPageRequest;
import com.ncmmall.querychannel.service.QueryChannelService;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableMap;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 直播商品池管理
 *
 * @author Samuel
 * @date 2020-9-3 18:01:28
 */
@Controller
@RequestMapping("/live/goods")
@Slf4j
public class AdminLiveGoodsController {

    @Autowired
    private QueryChannelService queryChannelService;

    @Autowired
    private LiveGoodsApplication liveGoodsApplication;

    /**
     * 列表
     */
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    public String list(Model model, QueryPageRequest pageRequest, LiveGoods params) {

        Map<String, Object> map = new HashMap<>();
        String hql = buildHQL(params, map);
        QueryPage<LiveGoods> page = queryChannelService.findPage(hql, pageRequest.setParams(map), LiveGoods.class);

        for (LiveGoods liveGoods : page.getResult()) {
            liveGoods.setAnchorNumber(queryChannelService.selectCount("select count(*) from live_goods_anchor where live_goods_id = :id", ImmutableMap.of("id", liveGoods.getId())));
        }

        model.addAttribute("page", page);
        model.addAttribute("params", params);

        List<GoodsChannel> channels = queryChannelService.findAll(QGoodsChannel.goodsChannel.level.eq(1).and(QGoodsChannel.goodsChannel.status.eq(1)).and(QGoodsChannel.goodsChannel.deleteStatus.eq(0)), GoodsChannel.class);
        model.addAttribute("channels", channels);

        return "mall/live/goods/list";
    }

    private String buildHQL(LiveGoods params, Map<String, Object> map) {

        String hql = "select g from LiveGoods g where (g.status = 1 or g.status = 2) ";
        Goods goods = params.getGoods();

        if (goods != null) {
            if (StringUtils.isNotBlank(goods.getName())) {
                hql += " and g.goods.name like :goodsName";
                map.put("goodsName", "%" + goods.getName() + "%");
            }

            if (null != goods.getGoodsChannel() && goods.getGoodsChannel().getId() > 0) {
                goods.setGoodsChannel(queryChannelService.findOne(QGoodsChannel.goodsChannel.id.eq(goods.getGoodsChannel().getId()), GoodsChannel.class));

                hql += " and g.goods.goodsChannel.id = :cid ";
                map.put("cid", goods.getGoodsChannel().getId());

            } else if (null != goods.getGoodsChannel() && goods.getGoodsChannel().getParent().getId() > 0) {
                goods.getGoodsChannel().setParent(queryChannelService.findOne(QGoodsChannel.goodsChannel.id.eq(goods.getGoodsChannel().getParent().getId()), GoodsChannel.class));

                hql += " and g.goods.goodsChannel.parent.id = :cid ";
                map.put("cid", goods.getGoodsChannel().getParent().getId());

            } else if (null != goods.getGoodsChannel() && goods.getGoodsChannel().getParent().getParent().getId() > 0) {
                goods.getGoodsChannel().getParent().setParent(queryChannelService.findOne(QGoodsChannel.goodsChannel.id.eq(goods.getGoodsChannel().getParent().getParent().getId()), GoodsChannel.class));

                hql += " and g.goods.goodsChannel.parent.parent.id = :cid ";
                map.put("cid", goods.getGoodsChannel().getParent().getParent().getId());
            }
        }

        if (params.getLiveScope() > 0) {
            hql += " and g.distributorScope = :scope";
            map.put("scope", params.getLiveScope());
        }

        if (params.getMinPrice() != null) {
            hql += " and g.goods.defaultPrice >= :minPrice";
            map.put("minPrice", params.getMinPrice());
        }

        if (params.getMaxPrice() != null && (params.getMinPrice() == null || params.getMaxPrice() > params.getMinPrice())) {
            hql += " and g.goods.defaultPrice <= :maxPrice";
            map.put("maxPrice", params.getMaxPrice());
        }

        hql += " order by g.createTime desc";
        return hql;
    }

    /**
     * 详情
     */
    @RequestMapping(value = "/detail", method = RequestMethod.GET)
    public String detail(Model model, long id) {
        LiveGoods liveGoods = queryChannelService.findOne(LiveGoods.class, id);
        model.addAttribute("liveGoods", liveGoods);
        return "mall/live/goods/detail";

    }

    /**
     * 移除直播池商品
     */
    @RequestMapping(value = "/remove", method = RequestMethod.PUT)
    @ResponseBody
    public Map<String, Object> remove(long id) {
        try {
            LiveGoods liveGoods = queryChannelService.findOne(LiveGoods.class, id);
            Requires.notNull(liveGoods, "商品不存在");

            liveGoodsApplication.remove(liveGoods);
            return ImmutableMap.of("status", true, "message", "移除成功");

        } catch (IllegalArgumentException e) {
            return ImmutableMap.of("status", false, "message", e.getMessage());
        } catch (Exception e) {
            log.error("[移除直播池商品异常]", e);
            return ImmutableMap.of("status", false, "message", "移除异常");
        }
    }


    /**
     * 上架直播池商品
     *
     * @param id 直播池商品id
     */
    @RequestMapping(value = "/enable", method = RequestMethod.PUT)
    @ResponseBody
    public Map<String, Object> enable(long id) {
        try {
            LiveGoods liveGoods = queryChannelService.findOne(LiveGoods.class, id);
            Requires.notNull(liveGoods, "商品不存在");

            liveGoodsApplication.enable(liveGoods);
            return ImmutableMap.of("status", true, "message", "上架成功");

        } catch (IllegalArgumentException e) {
            return ImmutableMap.of("status", false, "message", e.getMessage());
        } catch (Exception e) {
            log.error("[上架直播池商品异常]", e);
            return ImmutableMap.of("status", false, "message", "上架异常");
        }
    }


    /**
     * 下架直播池商品
     *
     * @param id 直播池商品id
     */
    @RequestMapping(value = "/disable", method = RequestMethod.PUT)
    @ResponseBody
    public Map<String, Object> disable(long id) {
        try {
            LiveGoods liveGoods = queryChannelService.findOne(LiveGoods.class, id);
            Requires.notNull(liveGoods, "商品不存在");


            liveGoodsApplication.disable(liveGoods);
            return ImmutableMap.of("status", true, "message", "下架成功");

        } catch (IllegalArgumentException e) {
            return ImmutableMap.of("status", false, "message", e.getMessage());
        } catch (Exception e) {
            log.error("[下架直播池商品异常]", e);
            return ImmutableMap.of("status", false, "message", "下架异常");
        }
    }


    /**
     * 批量移除直播池商品
     *
     * @param ids 直播池商品id
     */
    @RequestMapping(value = "/removes", method = RequestMethod.PUT)
    @ResponseBody
    public Map<String, Object> remove(String ids) {

        try {

            List<Long> longIds = Splitter.on(";").omitEmptyStrings().trimResults().splitToList(ids).stream().map(Long::valueOf).collect(Collectors.toList());
            Requires.notEmpty(longIds, "请选择商品");

            List<LiveGoods> liveGoodPools = queryChannelService.findAll(QLiveGoods.liveGoods.id.in(longIds), LiveGoods.class);
            liveGoodsApplication.removes(liveGoodPools);

            return ImmutableMap.of("status", true, "message", "移除成功");

        } catch (IllegalArgumentException e) {
            return ImmutableMap.of("status", false, "message", e.getMessage());
        } catch (Exception e) {
            log.error("[批量移除直播池商品异常]", e);
            return ImmutableMap.of("status", false, "message", "移除异常");
        }
    }


    /**
     * 查看指定直播间
     */
    @RequestMapping(value = "/{id}/queryAssignDistributor", method = RequestMethod.GET)
    public String queryAssignDistributor(Model model, PageParams pageParams, @PathVariable("id") long id) {
        QueryPageRequest pageRequest = new QueryPageRequest().setPageNo(pageParams.getPageNo());
        String hql = "select d.anchor from LiveGoodsAnchor d where d.liveGoods.id = :did";
        QueryPage<WebUser> page = queryChannelService.findPage(hql, pageRequest.setParams(ImmutableMap.of("did", id)), WebUser.class);
        model.addAttribute("page", page);
        return "mall/live/goods/queryAssignDistributor";
    }

    /**
     * 编辑排序值
     */
    @RequestMapping(value = "/{id}/modifyRank", method = RequestMethod.GET)
    private String modifyRank(Model model, @PathVariable("id") long id) {
        LiveGoods liveGoods = queryChannelService.findOne(LiveGoods.class, id);
        model.addAttribute("liveGoods", liveGoods);
        return "mall/live/goods/modifyRank";
    }

    /**
     * 编辑排序值
     */
    @RequestMapping(value = "/{id}/modifyRank", method = RequestMethod.PUT)
    @ResponseBody
    private Map<String, Object> modifyRank(@RequestHeader("X-Requested-With") String requestWith, @ModelAttribute LiveGoods liveGoods) {
        try {
            if (!Webs.isAjaxRequest(requestWith)) {
                throw new IllegalRequestException("request must be ajax !");
            }

            liveGoodsApplication.modifyRank(liveGoods);

            return ImmutableMap.of("status", true);
        } catch (Exception e) {
            log.error("[编辑排序值异常]", e);
            return ImmutableMap.of("status", false);
        }
    }
}
